using System;
using System.Collections.Generic;
using System.Text;
using SanFS.DiscLibrary;
using SanFS.Logging;
using SanFS.MediaChangerLibrary;
using System.Threading;

namespace SanFS.MediaChangerService
{
    internal class ScanInventoryJob : JobRequest
    {
        private int mStart;
        private int mEnd;
        private int mSavedPosition = -1;

        public ScanInventoryJob(MediaChangerService Service, int Start, int End)
            : base(Service)
        {
            mStart = Start;
            mEnd = End;
        }

        protected override void RunJob()
        {
            int actualStart = (mSavedPosition == -1) ? mStart : mSavedPosition;
            int currentSlot = actualStart;

            try
            {
                Log.WriteLine(Log.Layer.Scheduler, Log.Type.Debug, "Scanning {0} -> {1}", actualStart, mEnd);
                Service.MediaChanger.Reset();

                /// Determine how many drives and slots
                List<DataTransferStorageElement>    drives = new List<DataTransferStorageElement>();
                Queue<IStorageElement>              work = new Queue<IStorageElement>();
                Dictionary<Guid, IStorageElement>   mDiscGuidToElementMap = new Dictionary<Guid, IStorageElement>();
                Dictionary<Guid, IDisc>             mDiscGuidToDiscMap = new Dictionary<Guid, IDisc>();

                foreach (IStorageElement se in Service.MediaChanger.StorageElements)
                {
                    if (se is INormalStorageElement && se.Status == LoadStatus.Loaded)
                        work.Enqueue(se);
                    else if (se is DataTransferStorageElement)
                        drives.Add((DataTransferStorageElement) se);
                }

                /// XXX: This algorithm does not support multiple drives.
                /// I'll impliment later, if I ever get a multi drive device..
                while (work.Count > 0)
                {
                    IStorageElement se = work.Dequeue();
                    Disc            d = null;   // XXX: Fix this.. make a DiscFactory to not need to expose 'Disc' internals
                    Drive           drv = new Drive(drives[0].DevicePath, drives[0].MountPoint);

                    drives[0].Load(se);
                    d = new Disc();
                    d.RefreshPhysInfo(drv);
                    if (d.Status != EDiscStatus.Blank)
                    {
                        drv.Mount();
                        
                    }
                    
                }
            }
            catch (ThreadAbortException)
            {
                mSavedPosition = currentSlot;
                throw;
            }
        }
    }  // END CLASS
}  // END NAMESPACE
